Skip to content

Upgrade all dependencies across monorepo#892

Merged
marcodejongh merged 16 commits intomainfrom
claude/upgrade-dependencies-x6sAk
Mar 2, 2026
Merged

Upgrade all dependencies across monorepo#892
marcodejongh merged 16 commits intomainfrom
claude/upgrade-dependencies-x6sAk

Conversation

@marcodejongh
Copy link
Owner

  • Upgrade all packages to latest versions across web, backend, db, shared-schema, aurora-sync, crypto, and moonboard-ocr packages
  • Migrate backend from zod v3 to v4: update z.record() to require key schema, replace ZodError.errors with .issues, replace errorMap with error option in z.enum()
  • Remove deprecated stub type packages (@types/bcryptjs, @types/uuid) that now ship their own types
  • Fix vitest.config.ts vite plugin type mismatch from dual vite versions

Notable major version upgrades:

  • jose: 4.x → 6.x
  • zod (backend): 3.x → 4.x
  • nodemailer: 7.x → 8.x
  • commander: 12.x → 14.x
  • jsdom: 27.x → 28.x
  • @faker-js/faker: 9.x → 10.x
  • next: 16.1.1 → 16.1.6
  • @sentry/nextjs: 10.32.1 → 10.40.0

https://claude.ai/code/session_01JU1orYWk44pttrbyeriLrH

- Upgrade all packages to latest versions across web, backend, db,
  shared-schema, aurora-sync, crypto, and moonboard-ocr packages
- Migrate backend from zod v3 to v4: update z.record() to require key
  schema, replace ZodError.errors with .issues, replace errorMap with
  error option in z.enum()
- Remove deprecated stub type packages (@types/bcryptjs, @types/uuid)
  that now ship their own types
- Fix vitest.config.ts vite plugin type mismatch from dual vite versions

Notable major version upgrades:
- jose: 4.x → 6.x
- zod (backend): 3.x → 4.x
- nodemailer: 7.x → 8.x
- commander: 12.x → 14.x
- jsdom: 27.x → 28.x
- @faker-js/faker: 9.x → 10.x
- next: 16.1.1 → 16.1.6
- @sentry/nextjs: 10.32.1 → 10.40.0

https://claude.ai/code/session_01JU1orYWk44pttrbyeriLrH
@vercel
Copy link

vercel bot commented Mar 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
boardsesh Error Error Mar 2, 2026 2:21pm

Request Review

@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@claude
Copy link

claude bot commented Mar 1, 2026

Claude Review

Ready to merge - Minor issues noted below, but nothing blocking.

Minor Issues

  1. packages/web/vitest.config.ts:6 - The as any cast is a workaround for vite plugin type mismatch. While acceptable, consider adding a comment explaining why this is needed, or tracking an issue to fix the underlying dual vite versions problem.

  2. Major version jumps - Multiple packages have major version upgrades (jose 4→6, commander 12→14, nodemailer 7→8). The Zod v4 migration changes in packages/backend/src/validation/schemas.ts look correct (z.record() key schema, .issues instead of .errors, error instead of errorMap).

Verified

  • Zod v3→v4 migration in schemas.ts follows correct patterns
  • jose jwtDecrypt usage in auth.ts appears compatible with v6
  • nodemailer usage in email-service.ts appears compatible with v8
  • No documentation updates needed (no changes to documented systems)

vite was listed as a direct dependency in packages/web but is only used
transitively through vitest. This caused two vite versions to be
installed (7.3.0 at root from moonboard-ocr's vitest, 7.3.1 nested in
web), leading to a type mismatch between @vitejs/plugin-react and
vitest/config. Removing the direct dependency lets everything resolve
to a single hoisted version, eliminating the need for the `as any` cast
on the plugin.

https://claude.ai/code/session_01JU1orYWk44pttrbyeriLrH
@claude
Copy link

claude bot commented Mar 1, 2026

Claude Review

Ready to merge - The dependency upgrades are well-executed with proper Zod v4 migration. Minor notes below.

Notes

  1. Vercel deployment failure - The Vercel build is currently failing. Verify this is not caused by PR changes (may be transient).

  2. jose 4.x → 6.x - Major version jump; the jwtDecrypt usage in packages/backend/src/middleware/auth.ts appears compatible, but recommend verifying JWT decryption works in the backend integration tests.

  3. Removed vite direct dependency - Correct approach to avoid dual vite version type conflicts; vitest provides vite transitively.

claude and others added 12 commits March 2, 2026 14:49
Move BoardSeshHeader inside <main> to eliminate the double offset
caused by it sitting in the flow before main while main also has
paddingTop: var(--global-header-height). Also tighten ClimbsList
container and header box padding.

https://claude.ai/code/session_016LMRegRb8Y2AXmzj4zLceE
The climb list actions drawer had no opening animation because it was
conditionally rendered ({isActionsOpen && <SwipeableDrawer open={...}>}),
mounting already in the open state so MUI's Slide transition had no
"from" state. Fix by always rendering with open prop control and
keepMounted={false} for list performance.

Also convert 3 components using raw MUI Drawer to the shared
SwipeableDrawer for consistent swipe-to-close, responsive drag
handles, and animation behavior:
- gym-detail.tsx
- board-detail.tsx
- board-creation-banner.tsx

Fix conditional rendering in gym-search-results and board-search-results
that coupled data availability with open state, preventing animation.

https://claude.ai/code/session_01KR9PpCUWDVkV33uu3eUuRp
Remove the duplicate SearchPill from BoardSeshHeader and bridge the
climb filter drawer to the global header via a new SearchDrawerBridge
context. On the climb list page, the global header's search pill now
shows the filter summary (e.g. "V5-V7 · Tall") and opens the climb
filter accordion directly. On other pages it falls back to the generic
"Search" behavior.

- Create SearchDrawerBridgeContext with Provider/Injector/hook pattern
  (mirrors QueueBridge architecture)
- Add SearchDrawerBridgeProvider to PersistentSessionWrapper
- BoardSeshHeader registers with bridge on list pages, keeps the
  UnifiedSearchDrawer in the board route tree for context access
- GlobalHeader consumes bridge to show filter summary and active dot
- Delete unused SearchPill component and CSS module

https://claude.ai/code/session_01JNoJKNSydEBDLteHtYGk5g
- Add 13 tests for SearchDrawerBridgeContext covering:
  - Provider default state (no injector)
  - Injector register/deregister lifecycle
  - Summary and filter updates
  - openDrawer callback delegation
  - isOnListPage toggle behavior
- Update GlobalHeader tests (8 new) covering bridge integration:
  - Filter summary pill text display
  - Active indicator dot visibility
  - Click delegation to bridge drawer
  - Onboarding button ID transfer
  - Fallback to generic "Search" when bridge inactive
- Simplify SearchDrawerBridgeInjector: reduce 3 effects to 2 by
  using refs for mutable values, removing eslint-disable comments

All 1210 tests pass across 75 test files.

https://claude.ai/code/session_01JNoJKNSydEBDLteHtYGk5g
…docs

Replace useLayoutEffect with a useIsomorphicLayoutEffect wrapper that
falls back to useEffect on the server, preventing Next.js hydration
warnings. Update social-features-plan.md to replace deleted SearchPill
references with the current SearchDrawerBridge architecture.

https://claude.ai/code/session_011oaALoRPAYV5BfnAFLeFbR
When users visit a /b/slug/angle/list URL and then navigate home,
clicking the Climbs tab would generate an old-format URL from the
persistent session's board details instead of using the stored /b/ URL.

Fix the priority in handleClimbsTab to check getLastUsedBoard() first
when not on a board page, since it preserves the correct URL format.
Also store boardSlug in LastUsedBoardData and prefer /b/ URLs when
selecting saved configs that match a server board.

https://claude.ai/code/session_01Pb4dCMiY1L4RrzEDf8KT1n
- Restructure handleClimbsTab so the final fallback only triggers when
  isOnBoardPage && !listUrl, avoiding a duplicate async call
- Move config lookup before the server board match in handleSavedConfigSelect
  so layout/size/set metadata is passed to handleSelectBoard even when
  using a /b/ slug URL

https://claude.ai/code/session_01Pb4dCMiY1L4RrzEDf8KT1n
…l page

When viewing playlists from a board-scoped route, the list page now
filters by both boardType and layoutId (previously only boardType).
The playlist detail page now auto-selects the matching board filter
using SSR-fetched board data to avoid a flash from "All" to the
selected board.

- Add optional layoutId to GetAllUserPlaylistsInput GraphQL schema
- Update allUserPlaylists resolver to filter by layoutId (includes
  playlists with null layoutId for Aurora-synced circuits)
- Pass layoutId from library-page-content when board is selected
- Pass boardSlug/boardConfig to PlaylistDetailContent from both
  board slug and legacy route pages
- Fetch initialMyBoards server-side for instant board filter selection

https://claude.ai/code/session_018EN9pUTJVfWkza7fiicjuW
Fetch boards, user playlists, and discover playlists server-side and
pass as initial data to LibraryPageContent. This eliminates loading
skeletons on first render and ensures the board filter, playlist grid,
and discover sections render immediately from SSR.

- Add serverUserPlaylists() and cachedDiscoverPlaylists() to
  server-cached-client.ts
- Update LibraryPageContent to accept initialMyBoards,
  initialPlaylists, and initialDiscoverPlaylists props
- Use hasDataRef pattern to avoid re-showing loading skeleton on
  client-side refetches when SSR data is available
- Update all 3 playlist list page routes (board slug, legacy, global)
  to fetch SSR data in parallel and pass it down

https://claude.ai/code/session_018EN9pUTJVfWkza7fiicjuW
- Extract findMatchingBoard into shared utility (packages/web/app/lib/
  find-matching-board.ts), replacing duplicate implementations in
  library-page-content.tsx and playlist-detail-content.tsx
- Remove redundant client-side playlist filter (server already filters
  by boardType + layoutId)
- Simplify render conditions from (isAuthenticated || hasInitialPlaylistData)
  to just isAuthenticated
- Replace non-null assertion on or() with explicit type guard in
  allUserPlaylists resolver
- Add backend tests for allUserPlaylists resolver layoutId filtering
  (7 tests covering auth, boardType, layoutId, null layoutId, empty,
  ordering)
- Add frontend tests for findMatchingBoard utility (10 tests covering
  null/undefined/empty boards, slug matching, config matching,
  precedence)

https://claude.ai/code/session_018EN9pUTJVfWkza7fiicjuW
@claude
Copy link

claude bot commented Mar 2, 2026

Claude Review

Ready to merge - Minor issues noted below, but nothing blocking. The dependency upgrades and Zod v4 migration look correct, with comprehensive tests added for new functionality.

Minor Issues

  1. Node engine restriction tightened (package-lock.json): Engine changed from >=18 to 22.x. This is a breaking change for CI/CD or contributors running Node 18-21. Verify this is intentional.

  2. Scarf telemetry re-enabled (.npmrc deleted): Removing .npmrc re-enables scarf-js analytics telemetry (pulled in by swagger-ui-react). If privacy is a concern, consider keeping this opt-out.

  3. Empty UUID passed to detail components (packages/web/app/components/social/board-search-results.tsx:101, gym-search-results.tsx): Changed from conditional rendering to always rendering with boardUuid={selectedBoardUuid ?? ''}. While functionally okay (since open={!!selectedBoardUuid} is false), passing empty string as UUID is a minor code smell. Consider keeping the conditional render or using a sentinel value.

Test Coverage

Good test coverage added for new functionality:

  • allUserPlaylists resolver tests for layoutId filtering
  • SearchDrawerBridgeContext tests for registration/deregistration
  • getContextAwareClimbViewUrl and constructBoardSlugViewUrl tests
  • findMatchingBoard utility tests

Documentation

No doc updates needed - changes don't affect documented systems in docs/.

@claude
Copy link

claude bot commented Mar 2, 2026

Claude Review

Ready to merge - Dependency upgrades and Zod v4 migration look correct. Minor observations below, but nothing blocking.

Observations

  1. Large PR scope: This PR combines dependency upgrades (including breaking version changes) with new features (search drawer bridge, playlist layoutId filtering, context-aware URL utilities). Consider splitting these in the future for easier review and safer rollbacks.

  2. Node.js version change (>=1822.x): This is a breaking change for CI/CD and developer environments. Ensure all environments are updated to Node 22.x before merging.

  3. --legacy-peer-deps removal from vercel.json: If this was added to resolve peer dependency conflicts, removing it could cause deployment issues. Monitor the first deployment after merge.

Zod v4 Migration - Looks Correct

  • z.record() now requires key schema: ✓ Added z.string() as first argument
  • ZodError.errors.issues: ✓ Updated in validateInput
  • errorMaperror option in z.enum(): ✓ Updated for BoardNameSchema and TickStatusSchema

Test Coverage - Good

  • New all-user-playlists.test.ts covers authentication, filtering (boardType, layoutId), and edge cases (null layoutId for Aurora circuits)
  • New search-drawer-bridge-context.test.tsx added
  • New find-matching-board.test.ts and url-utils.test.ts additions

Documentation

  • docs/social-features-plan.md updated to reflect SearchDrawerBridgeInjector replacing SearchPill - good.

@claude
Copy link

claude bot commented Mar 2, 2026

Claude Review

Ready to merge - Minor issues noted below, but nothing blocking.

Issues

  1. .npmrc deletion re-enables telemetry - Deleting .npmrc removes the SCARF_ANALYTICS=false setting, which will re-enable Scarf telemetry from swagger-ui-react. If the original intent was to disable this telemetry, consider keeping the file or moving the setting elsewhere.

  2. Unused variable filtersActive (packages/web/app/components/board-page/header.tsx:55-56) - The code defines const filtersActive = hasActiveFilters(uiSearchParams) at the top but then calls hasActiveFilters(uiSearchParams) again inline in the render logic. Consider removing the top-level variable or using it consistently.

Test Quality

New tests are well-structured with good coverage:

  • all-user-playlists.test.ts: Tests auth requirements, filtering, null layoutId handling, and empty results
  • cors.test.ts: Comprehensive CORS validation including Tailscale hostname parsing, regex security, and edge cases
  • search-drawer-bridge-context.test.tsx: Tests registration/deregistration lifecycle and state updates

Documentation

No documentation updates needed - changes don't affect documented systems in docs/.

@marcodejongh marcodejongh merged commit 7705032 into main Mar 2, 2026
9 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants